﻿#pragma once
#include<vector>
#include<string>
#include<map>
#include<algorithm>//快排
#include<set>
#include"FA.h"
#include"Define.h"
using namespace std;

#define DEFAULT_FA		DFA//默认自动机类型
#define	DEFAULT_DATA	WORDTYPE//默认数据类型


//单词类型
enum class WORDTYPE
{
	WT_KEYWORD,//关键字
	WT_IDENTIFY,//标识符
	WT_WORD,//关键字、标识符	
	WT_REAL,//实数
	WT_INTEGER,//整数
	WT_CONSTANT,//常数
	WT_CHAR,//字符
	WT_STRING,//字符串
	WT_SIGN,//符号
	WT_WHITE,//空白
	WT_END,//结束符
	WT_WRONG//不存在
};

//单词（用于信息交流）
struct WORD
{
	DEFAULT_DATA type;//类型
	union
	{
		const wchar_t* c;//字符
		const wstring* str;//字符串
		const int* _int;//整数
		const double* _double;//双精度
		const BYTE* byte;//保留类型
		long long unsigned num;//序号
	}data;
};
//状态转换符号类型(符号集，一定程度上方便存放压缩)
struct SIGNSET
{
public:
	/*成员*/
	pair<wchar_t, wchar_t> range;//字符集合范围(确保输入范围first<second)
	SIGNSET(wchar_t c)
	{
		range = pair<wchar_t, wchar_t>(c, c);
	}
	SIGNSET(pair<wchar_t, wchar_t> char_range)
	{
		range = char_range;
	}
	SIGNSET(wchar_t first, wchar_t last)
	{
		range = pair<wchar_t, wchar_t>(first, last);
	}
	bool operator==(const SIGNSET& p);
	bool operator<=(const SIGNSET& p);//这里的<=为包含于
	static vector<SIGNSET> Div(vector<SIGNSET>& sets);
};
vector<SIGNSET> SIGNSET::Div(vector<SIGNSET>& sets)
{
	vector<pair<wchar_t, bool>> point;
	for (unsigned int i = 0; i < sets.size(); i++)
	{
		pair<wchar_t, bool>rem = pair<wchar_t, bool>(sets[i].range.first, false);
		unsigned int j = 0;
		for (; j < point.size(); j++)
		{
			if (point[j] == rem)break;
		}
		if (j >= point.size())point.push_back(rem);
		rem = pair<wchar_t, bool>(sets[i].range.second, true);
		j = 0;
		for (; j < point.size(); j++)
		{
			if (point[j] == rem)break;
		}
		if (j >= point.size())point.push_back(rem);
	}
	sort(point.begin(), point.end());
	vector<SIGNSET> rem_sets;
	long long unsigned int i = 0;
	for (; i + 1u < point.size(); i++)
	{
		wchar_t first = point[i].first, second = point[i + 1u].first;
		if (point[i].second)first++;
		if (!point[i + 1u].second)second--;
		rem_sets.push_back(SIGNSET(first, second));
	}
	return rem_sets;
}
bool SIGNSET :: operator==(const SIGNSET& p)
{
	if (this->range.first == p.range.first && this->range.second == p.range.second)
	{
		return true;
	}
	else
	{
		return false;
	}
}
bool SIGNSET :: operator<=(const SIGNSET& p)
{
	if (this->range.first >= p.range.first && this->range.second <= p.range.second)
	{
		return true;
	}
	else
	{
		return false;
	}
}

//简单词法分析器(根据已有自动机识别单词)
template<typename ACTION>
class SLA
{
private:
	int now_line = 0;
protected:
	DEFAULT_FA<SIGNSET, DEFAULT_DATA> FA;
	ACTION action;//动作
	//用于一些派生函数暂时不初始化参数的情况
public:
	//(状态表，状态转换矩阵，当前状态)
	SLA(DEFAULT_FA<SIGNSET, DEFAULT_DATA> _FA)
		:FA(_FA)
	{

	}
	/*识别一个单词(待识别串，识别起始位置，是否消除起始的空白字符)
	返回识别结果*/
	WORD Analyse(wstring pString, long long unsigned int& iPosition, bool WhiteChar = false);

	/*当前行数
	返回当前行数*/
	int GetNowLine() { return now_line; }
	/*设置当前行数
	返回当前行数*/
	void SetNowLine(int Line) { now_line = Line; }
	///*识别多个单词到(待识别串，识别起始位置)
	//返回识别结果*/
	//void Analyses(string pString, int& iPosition);
};
template<typename ACTION>
WORD SLA<ACTION>::Analyse(wstring pString, long long unsigned int& iPosition, bool WhiteChar)
{
	long long unsigned int now_position = iPosition;//当前读取位置
	long long unsigned int last_position = iPosition;//最后一个终止状态时读取位置
	STATEID last_final = 0;//最后一个中止状态
	FA.ToState(0);//初始化状态
	if (WhiteChar)
	{
		while (now_position < pString.size() && ((pString[now_position] >= '\t' && pString[now_position] <= '\r') || pString[now_position] == ' '))
		{
			if (pString[now_position] == '\n')
			{
				now_line++;
			}
			now_position++;
		}
		iPosition = now_position;
	}
	while (now_position < pString.size())
	{
		STATEID num;//返回状态值
		if (pString[now_position] == '\n')
		{
			now_line++;
		}

		num = FA.Read(pString[now_position++]);
		if (num == ABSENCE)
		{
			break;
		}
		if (FA.IsFinal())
		{
			last_position = now_position;
			last_final = num;
		}
	}
	if (FA.IsFinal())
	{
		//非终态，识别失败
	}
	if (last_final)
	{
		//默认优先匹配第一个类型(一个终态可能作为多个表达式的结尾状态)
		long long unsigned int rem = iPosition;
		iPosition = last_position;
		return action.action(FA.GetStateData(last_final)[0], (pString.substr(rem, last_position - rem)));
	}
	else
	{
		return action.action(DEFAULT_DATA::WT_WRONG, pString.substr(iPosition, last_position - iPosition));
	}
}

//词法分析器(可根据正则表达式自动生成自动机用于识别)
template<typename ACTION>
class LEX :public SLA<ACTION>
{

public:
	//(正则表达式，当前状态)
	LEX(vector<wstring> reExpress, int inState = 0)
		:SLA<ACTION>(DEFAULT_FA<SIGNSET, DEFAULT_DATA>(ENFA<SIGNSET, DEFAULT_DATA>(reExpress)))
	{

	}
};


